package com.tanhua.app.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.tanhua.UserHolder;
import com.tanhua.api.db.UserInfoApi;
import com.tanhua.api.mongo.CommentApi;
import com.tanhua.api.mongo.PublishApi;
import com.tanhua.db.UserInfo;
import com.tanhua.mongo.Comment;
import com.tanhua.mongo.Publish;
import com.tanhua.template.OssTemplate;
import com.tanhua.utils.RelativeDateFormat;
import com.tanhua.vo.PageBeanVo;
import com.tanhua.vo.PublishVo;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

@Service
public class QuanZiService {

    @Autowired
    private OssTemplate ossTemplate;

    @Reference
    private PublishApi publishApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Reference
    private CommentApi commentApi;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    //state:0 未审核  1 审核通过  2 审核不通过
    public ResponseEntity publishMovements(Publish publish, MultipartFile[] imageContent) throws IOException {
       //先将图片上传到oss中
        List<String> imgAddrList=new ArrayList();
       if(imageContent.length>0){
           for (MultipartFile multipartFile : imageContent) {
               String url = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
               imgAddrList.add(url);
           }
           //设置oss的地址
           publish.setMedias(imgAddrList);
       }
        publish.setUserId(UserHolder.getUser().getId());
        publish.setState(0); //未审核
       // 调用api做保存 publish表
        String publishId = publishApi.savePublish(publish);

        //做审核（华为云）==rockerMq
        rocketMQTemplate.convertAndSend("tanhua-quanzi",publishId);


        return ResponseEntity.ok(null);
    }

    public ResponseEntity findPublishAll(Integer page, Integer pagesize, Long userId) {

        //1 根据用户的id查询自己的所有动态id(根据动态id获取所有的动态信息)  返回分页
        PageBeanVo pageBeanVo=publishApi.findPublishAll(page,pagesize,userId);
        //3 查询自己的信息（userInfo）
        UserInfo userInfo = userInfoApi.findById(userId);
        //4 将自己的信息和动态发布的信息组装成app需要的Publishvo(publish+userInfo)
        List<Publish> items = (List<Publish>) pageBeanVo.getItems();

        List<PublishVo> voList=new ArrayList<PublishVo>();

        if(CollectionUtil.isNotEmpty(items)){
            PublishVo vo=null;
            for (Publish publish : items) {
                vo= new PublishVo();
                //封装用户数据
                BeanUtils.copyProperties(userInfo,vo);
                vo.setTags(userInfo.getTags().split(","));
                //封装用户动态数据
                BeanUtils.copyProperties(publish,vo);
                String[] imgs = publish.getMedias().toArray(new String[]{});
                vo.setImageContent(imgs);
                //将Long类型的毫秒日期转成xx分钟/小时/月前的格式工具
                String date = RelativeDateFormat.format(new Date(publish.getCreated()));
                vo.setCreateDate(date); //格式：类似10分钟前
                vo.setDistance("5.12公里"); //暂且死数据
                vo.setId(publish.getId().toString());
                //将没每个vo放入集合中
                voList.add(vo);
            }
        }
        pageBeanVo.setItems(voList); //空内容
        //5 返回vo
        System.out.println(pageBeanVo);
        return ResponseEntity.ok(pageBeanVo);
    }

    public ResponseEntity findFriendPublish(Integer page, Integer pagesize) {

        // 分页获取publish的数据
        PageBeanVo pb = publishApi.findFriendPublish(page, pagesize, UserHolder.getUser().getId());
        List<Publish> items = (List<Publish>) pb.getItems();
        // 获取userinfo的数据
        ArrayList<PublishVo> voList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(items)){
            for (Publish publish : items) {
                PublishVo vo = new PublishVo();
                //封装userInfo
                UserInfo userInfo = userInfoApi.findById(publish.getUserId());
                vo.setUserInfo(userInfo);
                vo.setPublish(publish);
                //告知app当前动态是否被点过赞 如果点赞了就会显示高亮 如果没点赞就不显示高亮
                Boolean flag = stringRedisTemplate.hasKey(StrUtil.format("publish_like_comment_{}_{}", UserHolder.getUser().getId(), publish.getId()));
                if(flag){
                    vo.setHasLiked(1); //点赞过 要高亮
                }else{
                    vo.setHasLiked(0); //没点赞过 不高亮
                }


                voList.add(vo);
            }
        }

        pb.setItems(voList);

        return ResponseEntity.ok(pb);
    }

    public ResponseEntity findRecommendPublish(Integer page, Integer pagesize) {



        //大数据推荐的
        PageBeanVo pb=fromRedisBigData(page,pagesize,UserHolder.getUser().getId());

        if(pb==null){
            // 分页获取publish的数据--recommend_user
            pb=publishApi.findRecommendPublish(page,pagesize,UserHolder.getUser().getId());
        }




        List<Publish> items = (List<Publish>) pb.getItems();
        // 获取userinfo的数据
        ArrayList<PublishVo> voList = new ArrayList<>();
        if(CollectionUtil.isNotEmpty(items)){
            for (Publish publish : items) {
                PublishVo vo = new PublishVo();
                //封装userInfo
                UserInfo userInfo = userInfoApi.findById(publish.getUserId());
                vo.setUserInfo(userInfo);
                vo.setPublish(publish);
                //告知app当前动态是否被点过赞 如果点赞了就会显示高亮 如果没点赞就不显示高亮

                //判断redis是否有标记 没有：0  有：1
                Boolean flag = stringRedisTemplate.hasKey(StrUtil.format("publish_like_comment_{}_{}", UserHolder.getUser().getId(), publish.getId()));
                if(flag){
                    vo.setHasLiked(1); //点赞过 要高亮
                }else{
                    vo.setHasLiked(0); //没点赞过 不高亮
                }
                Boolean flag2 = stringRedisTemplate.hasKey(StrUtil.format("publish_love_comment_{}_{}", UserHolder.getUser().getId(), publish.getId()));
                if(flag2){
                    vo.setHasLoved(1); //喜欢过 要高亮
                }else{
                    vo.setHasLoved(0); //没喜欢过 不高亮
                }
                voList.add(vo);
            }
        }

        //封装 返回
        pb.setItems(voList);
        return ResponseEntity.ok(pb);
    }



    //点赞
    public ResponseEntity likePublish(String publishId) {
        // 封装可变数据
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(1);
        comment.setPubType(1);
        comment.setUserId(UserHolder.getUser().getId());
        Integer count = commentApi.save(comment);

        //记录redis
        stringRedisTemplate.opsForValue().set(StrUtil.format("publish_like_comment_{}_{}", UserHolder.getUser().getId(), publishId),"1");
        return ResponseEntity.ok(count);
    }

    //取消点赞
    public ResponseEntity unlikePublish(String publishId) {
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(1);
        comment.setPubType(1);
        comment.setUserId(UserHolder.getUser().getId());
        Integer count = commentApi.delete(comment);
        //redis删除
        stringRedisTemplate.delete(StrUtil.format("publish_like_comment_{}_{}", UserHolder.getUser().getId(), publishId));

        return ResponseEntity.ok(count);
    }

    //喜欢
    public ResponseEntity lovePublish(String publishId) {
        // 封装可变数据
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(3);
        comment.setPubType(1);
        comment.setUserId(UserHolder.getUser().getId());
        Integer count = commentApi.save(comment);

        //记录redis
        stringRedisTemplate.opsForValue().set(StrUtil.format("publish_love_comment_{}_{}", UserHolder.getUser().getId(), publishId),"1");
        return ResponseEntity.ok(count);
    }

    public ResponseEntity unlovePublish(String publishId) {
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));
        comment.setCommentType(3);
        comment.setPubType(1);
        comment.setUserId(UserHolder.getUser().getId());
        Integer count = commentApi.delete(comment);
        //redis删除
        stringRedisTemplate.delete(StrUtil.format("publish_love_comment_{}_{}", UserHolder.getUser().getId(), publishId));

        return ResponseEntity.ok(count);
    }

    public ResponseEntity findByPublish(String publishId) {

        // 根据动态id查询publish
        Publish publish=publishApi.findById(publishId);
        // 查询userInfo
        UserInfo userInfo = userInfoApi.findById(publish.getUserId());
        // 组装publishVo
        PublishVo publishVo = new PublishVo();
        publishVo.setUserInfo(userInfo);
        publishVo.setPublish(publish);
        System.out.println(publishVo);
        return ResponseEntity.ok(publishVo);
    }



    public void toBigDate(int type, String publishId) {

        Map map=new HashMap<>();
        map.put("type",type);
        map.put("userId",UserHolder.getUser().getId());

        //根据publishId获取publish对象
        Publish publish = publishApi.findById(publishId);
        map.put("pid",publish.getPid());
        rocketMQTemplate.convertAndSend("tanhua-bigdata",map);


    }





    //从redis中拿到大数据给推荐的数据
    private PageBeanVo fromRedisBigData(Integer page, Integer pagesize, Long userId) {

        String value = stringRedisTemplate.opsForValue().get("QUANZI_PUBLISH_RECOMMEND_" + userId);
        if(value==null){
            return null;
        }
        String[] pids = value.split(",");
        Integer count=pids.length; //总条数
        //redis分页

        int start=(page-1)*pagesize;
        if(start>count){
            return null;
        }


        int end=page*pagesize;
        if(end>count){
            end=count;
        }

        List<Publish> publishList = new ArrayList<>();
        for(int i=start;i<end;i++){
            Publish publish=publishApi.findByPid(pids[i]);
            publishList.add(publish);
        }



        return new PageBeanVo(page,pagesize,count.longValue(),publishList);
    }
}
